﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WorkStation.Frameworks.Core.Wcf
{
    /// <summary>
    /// * WCF服务调用器
    /// </summary>
    public class ServiceInvoker
    {
        /// <summary>
        /// * 调用WCF服务方法（没有返回值的方法）
        /// </summary>
        /// <typeparam name="TChannel">通道类型</typeparam>
        /// <param name="funcation">调用方法</param>
        /// <param name="endpointName">终结点名称</param>
        public static void Invoke<TChannel>(Action<TChannel> funcation, string endpointName)
        {
            TChannel proxy = ServiceProxyFactory.CreateChannel<TChannel>(endpointName);
            ICommunicationObject channel = proxy as ICommunicationObject;
            
            if (channel == null)
            {
                throw new Exception(string.Format("【{0}】is not impletements the ICommunicationObject interface.", typeof(TChannel).FullName));
            }

            try
            {
                funcation(proxy);
            }
            catch (TimeoutException ce)
            {
                channel.Abort();
                throw ce;
            }
            catch (CommunicationException ce)
            {
                channel.Abort();
                throw ce;
            }
            finally
            {
                channel.Close();
            }
        }

        /// <summary>
        /// * 调用WCF服务方法（没有返回值的方法）（以服务接口的实现类名称为终结点名称）
        /// </summary>
        /// <typeparam name="TChannel">通道类型</typeparam>
        /// <param name="funcation">调用方法</param>
        public static void Invoke<TChannel>(Action<TChannel> funcation)
        {
            Type channelType = typeof(TChannel);

            string endpointName = channelType.Name.Substring(1);

            ServiceInvoker.Invoke<TChannel>(funcation);
        }

        /// <summary>
        /// * 调用WCF服务方法（有返回值的方法）
        /// </summary>
        /// <typeparam name="TChannel">通道类型</typeparam>
        /// <typeparam name="TResult">返回值类型</typeparam>
        /// <param name="funcation">调用方法</param>
        /// <param name="endpointName">终结点名称</param>
        /// <returns></returns>
        public static TResult Invoke<TChannel, TResult>(Func<TChannel, TResult> funcation, string endpointName)
        {
            TChannel proxy = ServiceProxyFactory.CreateChannel<TChannel>(endpointName);
            ICommunicationObject channel = proxy as ICommunicationObject;

            if (channel == null)
            {
                throw new Exception(string.Format("【{0}】is not impletements the ICommunicationObject interface.", typeof(TChannel).FullName));
            }

            try
            {
                return funcation(proxy);
            }
            catch (TimeoutException ce)
            {
                channel.Abort();
                throw ce;
            }
            catch (CommunicationException ce)
            {
                channel.Abort();
                throw ce;
            }
            finally
            {
                channel.Close();
            }

            return default(TResult);
        }

        /// <summary>
        /// * 调用WCF服务方法（有返回值的方法）（以服务接口的实现类名称为终结点名称）
        /// </summary>
        /// <typeparam name="TChannel">通道类型</typeparam>
        /// <typeparam name="TResult">返回值类型</typeparam>
        /// <param name="funcation">调用方法</param>
        /// <returns></returns>
        public static TResult Invoke<TChannel, TResult>(Func<TChannel, TResult> funcation)
        {
            Type channelType = typeof(TChannel);

            string endpointName = channelType.Name.Substring(1);

            return ServiceInvoker.Invoke<TChannel, TResult>(funcation, endpointName);
        }
    }
}
